package com.ruoyi.project.rate.controller;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.ruoyi.common.utils.security.ShiroUtils;
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.framework.web.page.TableDataInfo;
import com.ruoyi.project.rate.Constants;
import com.ruoyi.project.rate.Utils;
import com.ruoyi.project.rate.domain.DbLimit;
import com.ruoyi.project.rate.domain.Kh;
import com.ruoyi.project.rate.service.DbLimitService;
import com.ruoyi.project.rate.service.KhService;

@Controller
@RequestMapping("/rate/dbLimit")
public class DbLimitController extends BaseController {
	@Autowired
	private DbLimitService dbLimitService;
	@Autowired
	private KhService khService;

	@RequestMapping("/dbLimit")
	public String dbLimit(DbLimit dbLimit, ModelMap mmap) {
		mmap.put("dbLimit", dbLimit);
		mmap.put("deptList", Utils.level2DeptList());

		return "rate/dbLimitList";
	}
	
	@PostMapping("/list")
	@ResponseBody
	public TableDataInfo list(DbLimit dbLimit) {
		List<DbLimit> list = this.dbLimitService.findList(dbLimit);
		return getDataTable(list);
	}
	
	@RequestMapping("/add")
	public String add(DbLimit dbLimit, ModelMap mmap) {
		mmap.put("dbLimit", dbLimit);
		mmap.put("deptList", Utils.level2DeptList());
		
		return "rate/dbLimitForm";
	}
	
	@RequestMapping("/edit")
	public String edit(DbLimit dbLimit, ModelMap mmap) {
		String pageFlag = dbLimit.getPageFlag();
		
		if (StringUtils.isNotBlank(dbLimit.getId())) {
			dbLimit = this.dbLimitService.get(dbLimit);
			if (dbLimit == null) {
				throw new RuntimeException("找不到对应的数据！");
			}
			dbLimit.setPageFlag(pageFlag);
		}

		mmap.put("dbLimit", dbLimit);
		mmap.put("deptList", Utils.level2DeptList());
		
		return "rate/dbLimitForm";
	}
	
	@PostMapping("/save")
	@ResponseBody
	public AjaxResult save(DbLimit dbLimit) {
		String pageFlag = dbLimit.getPageFlag();
		if (!StringUtils.equalsAny(pageFlag, "ADD", "EDIT")) {
			throw new RuntimeException("error pageFlag.");
		}
		
		if (StringUtils.isBlank(dbLimit.getKhz())) {
			return AjaxResult.error("请选择考核组");
		}
		
		if (dbLimit.getDept() == null
				|| dbLimit.getDept().getDeptId() == null
				|| dbLimit.getDept().getDeptId() <= 0L) {
			return AjaxResult.error("请选择考核单位");
		}
		
		this.dbLimitService.save(dbLimit);

		return AjaxResult.success("保存成功！");
	}
	
	@RequestMapping("/delete/{id}")
	@ResponseBody
	public AjaxResult delete(@PathVariable("id") String id) {
		if (StringUtils.isBlank(id)) {
			throw new RuntimeException("请求参数错误：【id=" + id + "】");
		}

		DbLimit d = this.dbLimitService.get(id);
		if (d == null) {
			throw new RuntimeException("找不到对应的数据！");
		}

		this.dbLimitService.delete(d);

		return AjaxResult.success("删除成功！");
	}
	
	/**
	 * 督办结果检查
	 * @param dbLimit
	 * @param mmap
	 * @return
	 */
	@RequestMapping("/dbLimitCheck")
	public String dbLimitCheck(DbLimit dbLimit, ModelMap mmap) {
		dbLimit.setMonthId(Utils.lastMonth());
		mmap.put("dbLimit", dbLimit);

		return "rate/dbLimitCheckList";
	}
	
	@PostMapping("/dbLimitCheckList")
	@ResponseBody
	public TableDataInfo dbLimitCheckList(DbLimit dbLimit) {
		return getDataTable(this.getDbLimitCheckList(dbLimit));
	}
	
	@RequestMapping("/exportDbLimitCheckList")
	@ResponseBody
	public AjaxResult exportDbLimitCheckList(DbLimit dbLimit) {
		List<DbLimit> dbLimitList = this.getDbLimitCheckList(dbLimit);
		Map<String, String> khzDictMap = Utils.mapDictByValue(Constants.KHZ);
		
		Workbook wb = null;
		OutputStream out = null;
		String filename = "督办考核结果检查表" + dbLimit.getMonthId() + ".xlsx";
		try {
			wb = new SXSSFWorkbook(500);
			Sheet sheet;
			Row row;
			Cell cell;
			CellRangeAddress region;
			int rowIndex = 0;
			int colIndex = 0;
			
			CellStyle horizontalTextWithSongti11 = Utils.styleOfSongti11Horizontal(wb);
			CellStyle horizontalTextWithSongti20 = Utils.styleOfSongti20Horizontal(wb);
			
			sheet = wb.createSheet();
			wb.setSheetName(0, "督办考核汇总表");
			rowIndex = 0;
			
			// 一级表头 begin
			row = sheet.createRow(rowIndex++);
			row.setHeight((short)(50 * 20));
			colIndex = 0;
			cell = row.createCell(colIndex++);
			cell.setCellValue("督办工作考核汇总表" + dbLimit.getMonthId());
			cell.setCellStyle(horizontalTextWithSongti20);
			for (int i = 0; i < 6; i++) {
				cell = row.createCell(colIndex++);
				cell.setCellStyle(horizontalTextWithSongti20);
			}
			region = new CellRangeAddress(rowIndex-1, rowIndex-1, 0, colIndex - 1);
			sheet.addMergedRegion(region);
			// 一级表头 end
			
			// 二级表头 begin
			row = sheet.createRow(rowIndex++);
			row.setHeight((short)(40 * 20));
			colIndex = 0;
			cell = row.createCell(colIndex++);
			cell.setCellValue("业务考核组");
			cell.setCellStyle(horizontalTextWithSongti11);
			sheet.setColumnWidth(colIndex - 1, 15 * 256);
			cell = row.createCell(colIndex++);
			cell.setCellValue("考核单位");
			cell.setCellStyle(horizontalTextWithSongti11);
			sheet.setColumnWidth(colIndex - 1, 15 * 256);
			cell = row.createCell(colIndex++);
			cell.setCellValue("低分情况");
			cell.setCellStyle(horizontalTextWithSongti11);
			sheet.setColumnWidth(colIndex - 1, 30 * 256);
			cell = row.createCell(colIndex++);
			cell.setCellValue("中分情况");
			cell.setCellStyle(horizontalTextWithSongti11);
			sheet.setColumnWidth(colIndex - 1, 30 * 256);
			cell = row.createCell(colIndex++);
			cell.setCellValue("高分情况");
			cell.setCellStyle(horizontalTextWithSongti11);
			sheet.setColumnWidth(colIndex - 1, 30 * 256);
			cell = row.createCell(colIndex++);
			cell.setCellValue("考核结果");
			cell.setCellStyle(horizontalTextWithSongti11);
			sheet.setColumnWidth(colIndex - 1, 30 * 256);
			cell = row.createCell(colIndex++);
			cell.setCellValue("考核情况");
			cell.setCellStyle(horizontalTextWithSongti11);
			sheet.setColumnWidth(colIndex - 1, 30 * 256);
			// 二级表头 end
			
			// 督办情况 begin
			for (DbLimit db : dbLimitList) {
				String value;
				row = sheet.createRow(rowIndex++);
				colIndex = 0;
				cell = row.createCell(colIndex++);
				cell.setCellValue(khzDictMap.get(db.getKhz()));
				cell.setCellStyle(horizontalTextWithSongti11);
				cell = row.createCell(colIndex++);
				cell.setCellValue(db.getDept().getDeptName());
				cell.setCellStyle(horizontalTextWithSongti11);
				cell = row.createCell(colIndex++);
				value = db.getDownDesc();
				if (StringUtils.isNotBlank(value)) {
					value = value.replace("<br/>", "");
				}
				cell.setCellValue(value);
				cell.setCellStyle(horizontalTextWithSongti11);
				cell = row.createCell(colIndex++);
				value = db.getMidDesc();
				if (StringUtils.isNotBlank(value)) {
					value = value.replace("<br/>", "");
				}
				cell.setCellValue(value);
				cell.setCellStyle(horizontalTextWithSongti11);
				cell = row.createCell(colIndex++);
				value = db.getUpDesc();
				if (StringUtils.isNotBlank(value)) {
					value = value.replace("<br/>", "");
				}
				cell.setCellValue(value);
				cell.setCellStyle(horizontalTextWithSongti11);
				cell = row.createCell(colIndex++);
				cell.setCellValue(StringUtils.equals("APPROVED", db.getCheckResult()) ? "通过" : "不通过");
				cell.setCellStyle(horizontalTextWithSongti11);
				cell = row.createCell(colIndex++);
				value = db.getCheckDesc();
				if (StringUtils.isNotBlank(value)) {
					value = value.replace("<br/>", "");
				}
				cell.setCellValue(value);
				cell.setCellStyle(horizontalTextWithSongti11);
			}
			// 督办情况 end
			
			String filepath = Utils.getExportAbsoluteFile(filename);
			File file = new File(filepath);
			if (file.exists() && file.isFile()) {
				file.delete();
			}
			out = new FileOutputStream(filepath);
			wb.write(out);
			return AjaxResult.success(filename);
		} catch (Exception e) {
			e.printStackTrace();
			return AjaxResult.error("导出Excel失败，请联系网站管理员！");
		} finally {
			IOUtils.closeQuietly(wb);
			IOUtils.closeQuietly(out);
		}
	}
	
	private List<DbLimit> getDbLimitCheckList(DbLimit dbLimit) {
		if (StringUtils.isBlank(dbLimit.getPageFlag())) {
			throw new RuntimeException("error pageFlag.");
		}
		
		if (StringUtils.isBlank(dbLimit.getMonthId())) {
			return new ArrayList<DbLimit>();
		}
		
		Kh _kh = new Kh();
		_kh.setMonthId(dbLimit.getMonthId());
		_kh.setType(Constants.KH_TYPE_DU);
		if (Constants.PAGE_FLAG_SUBMIT.equals(dbLimit.getPageFlag())) {
			_kh.setCreateDept(ShiroUtils.getSysDept());
			dbLimit.setDept(ShiroUtils.getSysDept());
		} else {
			// _kh.setStatus(Constants.KH_STATUS_APPROVED);
		}
		List<Kh> khList = this.khService.findList(_kh);
		
		List<DbLimit> dbLimitList = this.dbLimitService.findList(dbLimit);
		Map<String, DbLimit> dbLimitMap = new HashMap<String, DbLimit>();
		Iterator<DbLimit> it = dbLimitList.iterator();
		while (it.hasNext()) {
			DbLimit limit = it.next();
			String key = limit.getKhz() + "_" + limit.getDept().getDeptId();
			if (dbLimitMap.containsKey(key)) {
				it.remove();
				continue;
			}
			dbLimitMap.put(key, limit);
			
			if (limit.getKfUp() != null && limit.getKfUp().compareTo(BigDecimal.ZERO) > 0
					&& limit.getKfUpCount() != null && limit.getKfUpCount() > 0) {
				limit.setUpDesc("扣" + limit.getKfUp() + "分以上的单位（最少" + limit.getKfUpCount() + "个）有：<br/>");
			}
			if (limit.getKfDown() != null && limit.getKfDown().compareTo(BigDecimal.ZERO) > 0
					&& limit.getKfDownCount() != null && limit.getKfDownCount() > 0) {
				limit.setDownDesc("扣" + limit.getKfDown() + "分以下的单位（最多" + limit.getKfDownCount() + "个）有：<br/>");
			}
			if (limit.getKfUp() != null && limit.getKfUp().compareTo(BigDecimal.ZERO) > 0
					&& limit.getKfUpCount() != null && limit.getKfUpCount() > 0
					&& limit.getKfDown() != null && limit.getKfDown().compareTo(BigDecimal.ZERO) > 0
					&& limit.getKfDownCount() != null && limit.getKfDownCount() > 0) {
				limit.setMidDesc("扣" + limit.getKfDown() + "-" + limit.getKfUp() + "分之间的单位有：<br/>");
			}
		}
		
		// 根据考核情况统计总数
		for (Kh kh : khList) {
			String key = kh.getKhz() + "_" + kh.getCreateDept().getDeptId();
			DbLimit limit = dbLimitMap.get(key);
			if (limit == null) {
				continue;
			}
			limit.setDwgsSj(limit.getDwgsSj() + 1);
			
			if (kh.getKf() == null) {
				continue;
			}
			
			if (limit.getKfUp() != null && limit.getKfUp().compareTo(BigDecimal.ZERO) > 0
					&& limit.getKfUpCount() != null && limit.getKfUpCount() > 0) {
				if (kh.getKf().compareTo(limit.getKfUp()) >= 0) {
					limit.setKfUpCountSj(limit.getKfUpCountSj() + 1);
					limit.setUpDesc(limit.getUpDesc() + kh.getDept().getDeptName() + "、");
				}
			}
			if (limit.getKfDown() != null && limit.getKfDown().compareTo(BigDecimal.ZERO) > 0
					&& limit.getKfDownCount() != null && limit.getKfDownCount() > 0) {
				if (kh.getKf().compareTo(limit.getKfDown()) < 0) {
					limit.setKfDownCountSj(limit.getKfDownCountSj() + 1);
					limit.setDownDesc(limit.getDownDesc() + kh.getDept().getDeptName() + "、");
				}
			}
			if (limit.getKfUp() != null && limit.getKfUp().compareTo(BigDecimal.ZERO) > 0
					&& limit.getKfUpCount() != null && limit.getKfUpCount() > 0
					&& limit.getKfDown() != null && limit.getKfDown().compareTo(BigDecimal.ZERO) > 0
					&& limit.getKfDownCount() != null && limit.getKfDownCount() > 0) {
				if (kh.getKf().compareTo(limit.getKfUp()) < 0 && kh.getKf().compareTo(limit.getKfDown()) >= 0) {
					limit.setMidDesc(limit.getMidDesc() + kh.getDept().getDeptName() + "、");
				}
			}
		}
		
		// 汇总考核结果
		for (DbLimit limit : dbLimitList) {
			StringBuilder checkDesc = new StringBuilder();
			limit.setCheckResult("APPROVED");
			if (limit.getDwgs() != null && limit.getDwgs() > 0) {
				if (limit.getDwgsSj() != limit.getDwgs()) {
					limit.setCheckResult("REJECTED");
				}
				checkDesc.append("应督办考核单位【" + limit.getDwgs() + "】个，实际【" + limit.getDwgsSj() + "】个；<br/>");
			}
			if (limit.getKfUp() != null && limit.getKfUp().compareTo(BigDecimal.ZERO) > 0
					&& limit.getKfUpCount() != null && limit.getKfUpCount() > 0) {
				if (limit.getKfUpCountSj() < limit.getKfUpCount()) {
					limit.setCheckResult("REJECTED");
				}
				checkDesc.append("应考核并扣除" + limit.getKfUp() + "分以上单位最少【" + limit.getKfUpCount() + "】个，实际【" + limit.getKfUpCountSj() + "】个；<br/>");
			}
			if (limit.getKfDown() != null && limit.getKfDown().compareTo(BigDecimal.ZERO) > 0
					&& limit.getKfDownCount() != null && limit.getKfDownCount() > 0) {
				if (limit.getKfDownCountSj() > limit.getKfDownCount()) {
					limit.setCheckResult("REJECTED");
				}
				checkDesc.append("应考核并扣除" + limit.getKfDown() + "分以下单位最多【" + limit.getKfDownCount() + "】个，实际【" + limit.getKfDownCountSj() + "】个；");
			}
			
			String _checkDesc = checkDesc.toString();
			if (_checkDesc.length() > 1) {
				_checkDesc = _checkDesc.substring(0, _checkDesc.length() - 1);
			}
			limit.setCheckDesc(_checkDesc + "。");
			
			if (StringUtils.isNoneBlank(limit.getUpDesc()) && limit.getUpDesc().endsWith("、")) {
				limit.setUpDesc(limit.getUpDesc().substring(0, limit.getUpDesc().length() - 1));
			}
			if (StringUtils.isNoneBlank(limit.getDownDesc()) && limit.getDownDesc().endsWith("、")) {
				limit.setDownDesc(limit.getDownDesc().substring(0, limit.getDownDesc().length() - 1));
			}
			if (StringUtils.isNoneBlank(limit.getMidDesc()) && limit.getMidDesc().endsWith("、")) {
				limit.setMidDesc(limit.getMidDesc().substring(0, limit.getMidDesc().length() - 1));
			}
		}
		
		Collections.sort(dbLimitList, new Comparator<DbLimit>() {
			@Override
			public int compare(DbLimit o1, DbLimit o2) {
				String khz1 = o1.getKhz();
				String khz2 = o2.getKhz();
				if (StringUtils.isNotBlank(khz1) && StringUtils.isNotBlank(khz2)) {
					return khz1.compareTo(khz2);
				}
				return 0;
			}
		});
		return dbLimitList;
	}
}